package com.git.smp.utils;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import com.git.smp.entity.SmpField;

public class XqueryUtil {
	
	public static void main(String[] args) throws IOException {
		List<SmpField> listField = new ArrayList<>();
		SmpField smpField = new SmpField();
		smpField.setFieldCode("Test1");
		smpField.setInOut("01");
		smpField.setFieldType("01");
		smpField.setStruct("01");
		smpField.setFieldRequire("01");
		smpField.setNodeType("01");
		smpField.setParentType("");
		listField.add(smpField);
		
		
		SmpField smpField5 = new SmpField();
		smpField5.setFieldCode("Test2");
		smpField5.setInOut("01");
		smpField5.setFieldType("01");
		smpField5.setStruct("02");
		smpField5.setFieldRequire("01");
		smpField5.setNodeType("01");
		smpField5.setParentType("");
		listField.add(smpField5);
		
		SmpField smpField1 = new SmpField();
		smpField1.setFieldCode("List");
		smpField1.setInOut("01");
		smpField1.setFieldType("01");
		smpField1.setStruct("01");
		smpField1.setFieldRequire("02");
		smpField1.setNodeType("03");
		smpField1.setParentType("");
		listField.add(smpField1);
		
		
		SmpField smpField2 = new SmpField();
		smpField2.setFieldCode("Detail");
		smpField2.setInOut("01");
		smpField2.setFieldType("01");
		smpField2.setStruct("01");
		smpField2.setFieldRequire("02");
		smpField2.setNodeType("02");
		smpField2.setParentType("List");
		listField.add(smpField2);
		
		
		SmpField smpField3 = new SmpField();
		smpField3.setFieldCode("summary");
		smpField3.setInOut("01");
		smpField3.setFieldType("01");
		smpField3.setStruct("01");
		smpField3.setFieldRequire("01");
		smpField3.setNodeType("01");
		smpField3.setParentType("Detail");
		listField.add(smpField3);
		
		
		
		SmpField smpField4 = new SmpField();
		smpField4.setFieldCode("resMsg");
		smpField4.setInOut("02");
		smpField4.setFieldType("01");
		smpField4.setStruct("01");
		smpField4.setFieldRequire("01");
		smpField4.setNodeType("01");
		smpField4.setParentType("");
		listField.add(smpField4);
		
		String result = XqueryUtil.createDoc(listField,"01","01","xmlRequest");//request bizHeader
		String result1 = XqueryUtil.createDoc(listField,"02","01","xmlRequest");//request bizBody
		result = result.replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("##", "\n");
		System.out.println(result);
		System.out.println(result1);
	}
	
	
	public static  String createDoc(List<SmpField> listField, String struct, String inOut,String bodyName) {
		Document doc = DocumentHelper.createDocument();
		Element element = null;
		if("01".equals(struct)) {
			element=  doc.addElement("bizHeader");
		}else {
			element =  doc.addElement("bizBody");
		}
		 try {
			buildElement(element,listField, struct, inOut,"",bodyName);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 
			
			  OutputFormat format = OutputFormat.createPrettyPrint(); // 设置输出编码
			  format.setEncoding("UTF-8"); // 去除空行 
			  format.setSuppressDeclaration(true);
			  
			  XMLWriter writer = null; 
			  ByteArrayOutputStream out = new ByteArrayOutputStream();
			  
			  try {
				writer = new XMLWriter(out, format);
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
			  try {
				writer.write(doc);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			  
			  String result = out.toString();
			  result = result.replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("##", "\n");
		 return result;
		
	}
	
	public static  void buildElement(Element parentelement,List<SmpField> listField, String struct, String inOut,String parent,String bodyName) throws IOException{
		
		for(SmpField smpField:listField) {
			if(smpField.getParentType()==null) {
				smpField.setParentType("");
			}
			if(struct.equals(smpField.getStruct())&& inOut.equals(smpField.getInOut()) && parent.equals(smpField.getParentType())) {
				if("01".equals(smpField.getNodeType())) {//单节点
					Element element =  parentelement.addElement(smpField.getFieldCode());
					element.setText("{fn:data($"+bodyName+"/"+parentelement.getPath()+"/"+smpField.getFieldCode()+")}");
				}else if("03".equals(smpField.getNodeType())) {//List节点
					Element element =  parentelement.addElement(smpField.getFieldCode());
					buildList(element, listField,  struct,  inOut, smpField.getFieldCode(),bodyName);
				}else if("02".equals(smpField.getNodeType())) {//detail节点
				}
			}
			
		}
		
		
	}


	private static void buildList(Element element, List<SmpField> listField, String struct, String inOut,
			String parent,String bodyName) throws IOException {
		
		String listTest = "";
		
		for(SmpField smpField:listField) {
			if(smpField.getParentType()==null) {
				smpField.setParentType("");
			}
			if(struct.equals(smpField.getStruct())&& inOut.equals(smpField.getInOut()) && parent.equals(smpField.getParentType()) && "02".equals(smpField.getNodeType())) {
				listTest+="{\n";
				listTest+="let $"+smpField.getFieldCode()+" := $"+bodyName+"/"+element.getPath()+"/"+smpField.getFieldCode()+"\n";
				listTest+="let $cnt := count($"+smpField.getFieldCode()+")\n";
				listTest+="for $index in (1 to $cnt)\n";
				listTest+="return (\n";
				String detailValue = buildDetail(smpField.getFieldCode(),  listField,  struct,  inOut,
						smpField.getFieldCode(), bodyName);
				listTest+=detailValue;
				listTest+=")\n";
				listTest+="}\n";
				
			}
		}
		
		
		element.setText(listTest.replaceAll("\n", "##"));
		
	}


	private static String buildDetail(String fieldCode, List<SmpField> listField, String struct, String inOut,
			String parent, String bodyName) throws IOException {
		Document doc = DocumentHelper.createDocument();
		Element element = null;
		element =  doc.addElement(fieldCode);
		
		for(SmpField smpField:listField) {
			if(smpField.getParentType()==null) {
				smpField.setParentType("");
			}
			if(struct.equals(smpField.getStruct())&& inOut.equals(smpField.getInOut()) && parent.equals(smpField.getParentType()) && "01".equals(smpField.getNodeType())) {
				Element fieldElement = element.addElement(smpField.getFieldCode());
				fieldElement.setText("{fn:data($"+fieldCode+"[position() = $index]/"+smpField.getFieldCode()+")}");
			}
		}
		 OutputFormat format = OutputFormat.createPrettyPrint(); // 设置输出编码
		  format.setEncoding("UTF-8"); // 去除空行
		  format.setSuppressDeclaration(true);
		 
		  XMLWriter writer;
			ByteArrayOutputStream out = new ByteArrayOutputStream();
		  
		  try {
			writer = new XMLWriter(out, format);
			writer.setEscapeText(false);
			writer.write(doc);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		 out.close();
		 String result =  out.toString();
		 
		 return result;
	}

}
